#pragma once
#include <set>
#include <cstring>
#include <sys/epoll.h>
#include <errno.h>
#include "Log.hpp"

namespace EpollModule
{
    class Epoller
    {
        const static int default_size = 16;
    public:
        Epoller()
            : _epfd(-1)
        {
        }
        void InitEpoll()
        {
            int n = ::epoll_create(default_size);
            if (n < 0)
            {
                lg(Fatal, "epoll_create error, error : %s errno:%d", strerror(errno), errno);
                exit(3);
            }
            lg(Info, "epoll_create success fd : ", n);
            _epfd = n;
        }
        void AddEvent(int sockfd, uint32_t events)
        {
            if(sockfd > 0) _fds.insert(sockfd);
            struct epoll_event ev;
            ev.data.fd = sockfd; // todo?????? 不是给内核的, 给用户的
            ev.events = events;
            int n = ::epoll_ctl(_epfd, EPOLL_CTL_ADD, sockfd, &ev);
            if (n < 0)
            {
                lg(Error, "epoll_ctl error op: epoll_ctl_add, error : %s errno:%d", strerror(errno), errno);
                return;
            }
        }
        void DelEvent(int sockfd)
        {
            if(sockfd > 0) _fds.erase(sockfd);
            int n = ::epoll_ctl(_epfd, EPOLL_CTL_DEL, sockfd, nullptr);
            if (n < 0)
            {
                lg(Error, "epoll_ctl error op: epoll_ctl_del, error : %s errno:%d", strerror(errno), errno);
                return;
            }
        }
        
        int EpollWait(struct epoll_event* events, int maxevents, int timeout)
        {
            return ::epoll_wait(_epfd, events, maxevents, timeout);
        }
        ~Epoller()
        {
            close(_epfd);
        }   
        void PrintList()
        {
            std::cout << "fds : ";
            for(auto & n : _fds)
            {
                std::cout << n << "  ";
            }
            std::cout << "\n";
        }
    private:
        int _epfd; // 创建的Epoll模型也通过文件描述符统一管理
        std::set<int> _fds; //fortest
    };
} // namespace
